<template>
  <div>
    <a-flex gap="middle">
      <a-range-picker v-model:value="dateRange" format="YYYY-MM-DD" :presets="rangePresets"/>

      <a-select
        v-model:value="kw"
        :options="sectors"
        option-filter-prop="name"
        :fieldNames="{'label':'name','value':'code'}"
        mode="multiple"
        :max-tag-count="2"
        :max-tag-placeholder="3"
        show-search
        allow-clear
        style="width: 280px"
        placeholder="Select a sector"></a-select>

      <a-button @click="getData" type="primary">查询</a-button>
    </a-flex>

    <div id="main"></div>
  </div>
</template>

<script>
import {mapState} from "vuex";
import { findCartesian } from "@/api/cartesian";
import { RangePicker,Select } from 'ant-design-vue';
import dayjs from "dayjs";
import { cloneDeep } from 'lodash';
import {filterObjectProperties} from "@/common/utils";
import {convertToChineseUnit} from "@/common/utils";


function findMinMax(data) {
    let max_value = -Infinity;
    let min_value = Infinity;
    let max_info = {};
    let min_info = {};

    // 遍历每个日期对象
    data.forEach(item => {
        const date = item.date;

        // 遍历每个属性（除了date）
        for (const key in item) {
            if (key !== 'date' && typeof item[key] === 'number') {
                const value = item[key];

                // 检查最大值
                if (value > max_value) {
                    max_value = value;
                    max_info = {
                        date: date,
                        key: key,
                        value: value
                    };
                }

                // 检查最小值
                if (value < min_value) {
                    min_value = value;
                    min_info = {
                        date: date,
                        key: key,
                        value: value
                    };
                }
            }
        }
    });

    return {
        max: max_info,
        min: min_info
    };
}

function sortLabelsBySum(labels, values) {

    const labelsWithSum = labels.map(label => {
        const code = label.code;
        let sum = 0;

        values.forEach(item => {
            if (item[code] !== undefined) {
                sum += item[code];
            }
        });

        return { ...label, sum };
    });

    return labelsWithSum.sort((a, b) => a.sum - b.sum);
}


export default{
    components: {
      ARangePicker: RangePicker,
      ASelect: Select
    },
    computed:{
      ...mapState('app',['sectors'])
    },
    data(){
        return {
            kw: [],
            dateRange: [dayjs().subtract(30,'day'),dayjs()],
            myChart: null,
            options: [],
            rangePresets: [
              { label: 'Last 7 Days', value: [dayjs().add(-7, 'd'), dayjs()] },
              { label: 'Last 14 Days', value: [dayjs().add(-14, 'd'), dayjs()] },
              { label: 'Last 30 Days', value: [dayjs().add(-30, 'd'), dayjs()] }
            ]
        }
    },
    mounted(){
      var chartDom = document.getElementById('main');

      var myChart = echarts.init(chartDom,
          null,
          {renderer: "canvas"});


      this.myChart = myChart;

      this.getData();

    },
    methods:{
      getData(){
        let params = {}


        if (this.dateRange){
          params.startDate = dayjs(this.dateRange[0]).format("YYYY-MM-DD")
          params.endDate = dayjs(this.dateRange[1]).format("YYYY-MM-DD")
        }

        findCartesian(params).then(res=>{
          this.updateChart(res.data);
        })


      },
      updateChart(data){


        let isFilter = false;

        let sectorMap = cloneDeep(this.sectors);

        const {max,min} = findMinMax(data);

        if (this.kw.length){
          isFilter = true;

          data = filterObjectProperties(data,['date'].concat(this.kw))

          sectorMap = sectorMap.filter(a=> this.kw.includes(a.code))

        }



        let sortedList = sortLabelsBySum(sectorMap,data);


        var absMax = Math.max(Math.abs(min.value), Math.abs(max.value));

        let days = [];

        let sectors = [];

        let chartData = [];


        let dindex = 0;

        sortedList.forEach(a=>{
          sectors.push(a.name);

        })


        data.forEach(a=>{

          let sum = 0;

          for (let b in a){
            if (b !== 'date'){

                let sindex = sortedList.findIndex(c=> c.code === b);

                chartData.push([dindex,sindex,a[b]])

                sum+= a[b]
            }
          }

          dindex++;

          days.push(`${dayjs(a.date).format("YYYY/MM/DD")}
${convertToChineseUnit(sum)}`)

        })

        let option = {
          tooltip: {
            position: 'top'
          },
          grid: {
            height: '100%',
            top: '40px',
            bottom: '20px'
          },
          xAxis: {
            type: 'category',
            data: days,
            splitArea: {
              show: true
            }
          },
          yAxis: {
            type: 'category',
            data: sectors,
            splitArea: {
              show: true
            }
          },
          visualMap: {
            show: false,
            calculable: false,
            hoverLink: false,
            min: -absMax,
            max: absMax,
            orient: 'vertical',
            left: '0',
            top: '0',
            inRange: {
                color: ['#008000','#ffffff','#ff0000']
            }
          },
          series: [
            {
              name: 'cartesian',
              type: 'heatmap',
              data: chartData,
              label: {
                show: false
              },
              symbolSize: function (data) {
                  return Math.log(Math.abs(data[2]) + 1) / 3 + 5;
              },
              tooltip: {
                show: true,
                formatter(params){
                  let color = 'green'

                  if (params.value[2] > 0){
                    color = 'red'
                  }

                  return `<b>${sortedList[params.data[1]].name}</b><span>${params.name}</span>
                  <p style="color:${color}">
                    <i style="border:1px solid ${color};vertical-align:sub;display:inline-block;width:12px;height:12px;margin-right:5px;background:${params.color}"></i>
                    ${convertToChineseUnit(Math.abs(params.value[2]))}</p>`
                }
              }
            }
          ],
        };


        this.$nextTick(()=>{
            this.myChart.resize({
                height: sectors.length * 34 + 200
            })


            this.myChart.setOption(option);
        })


      }
    }
}

</script>
